package client;

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.http.*;

import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;

/**
 * @author dsp
 * @date 2021-04-05
 */
public class NettyHttpClient {

    public static final int PORT = 8888;
    public static final String HOST = "127.0.0.1";

    public static void main(String[] args) {
        NettyHttpClient client = new NettyHttpClient();
        client.execute(HOST, PORT);
    }

    private void execute(String host, int port) {

        EventLoopGroup group = new NioEventLoopGroup();
        Bootstrap bootstrap = new Bootstrap();

        try {
            bootstrap.group(group)
                    .channel(NioSocketChannel.class)
                    .option(ChannelOption.SO_KEEPALIVE, true);
            bootstrap.handler(new ChannelInitializer<SocketChannel>() {
                @Override
                protected void initChannel(SocketChannel ch) throws Exception {
                    ch.pipeline().addLast(new HttpClientCodec());
                    ch.pipeline().addLast("objectAggregator", new HttpObjectAggregator(2048));
                    ch.pipeline().addLast("contentDecompressor", new HttpContentDecompressor());
                    ch.pipeline().addLast("nettyHttpClientHandler", new NettyHttpClientHandler());
                }
            });
            ChannelFuture channelFuture = bootstrap.connect(host, port).sync();
            // 请求服务端
            URI uri = new URI("/test");
            String data = "Hello Netty";
            DefaultFullHttpRequest req = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET,
                    uri.toASCIIString(), Unpooled.wrappedBuffer(data.getBytes(StandardCharsets.UTF_8)));
            req.headers().set(HttpHeaderNames.HOST, host);
            req.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE);
            req.headers().set(HttpHeaderNames.CONTENT_LENGTH, req.content().readableBytes());
            req.headers().set("token", "asd");
            System.out.println("请求context --> " + data);
            System.out.println("请求额外headers --> " + "token: asd");

            channelFuture.channel().write(req);
            channelFuture.channel().flush();
            channelFuture.channel().closeFuture().sync();

        } catch (URISyntaxException | InterruptedException e) {
            e.printStackTrace();
        } finally {
            try {
                group.shutdownGracefully().sync();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
